<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
    <style>
        * {
            margin: 0;
            padding: 0;
        }
    </style>
</head>

<body>
    <canvas id="canvas"></canvas>
</body>
<script id="ColorVertexShader" type="x-shader/x-vertex">
    attribute vec4 a_Position;
    uniform float u_PointSize;
    uniform mat4 u_ModelM4;
    uniform mat4 u_PvM4;
    void main(){
        gl_Position = u_PvM4 * u_ModelM4 * a_Position;
        gl_PointSize = u_PointSize;
    }
</script>
<script id="ColorFragmentShader" type="x-shader/x-fragment">
    precision mediump float;
    uniform vec4 u_Color;
    void main(){
        gl_FragColor = u_Color;
    }
</script>
<script type="module">
    import { Matrix4, Vector3, Color, OrthographicCamera, PerspectiveCamera, Spherical } from '../js/three.module.js';
    import { CreateProgram, imgPromise } from '../js/Utils.js';
    import lib from '../js/ThreeLib.js';
    import CameraController from '../js/CameraController.js'
    import Poly from '../js/Poly4.js'
    import Control from '../js/Control.js'

    import Geo from '../js/Poly2/Geo.js'
    import Mat from '../js/Poly2/Mat.js'
    import Obj3D from '../js/Poly2/Obj3D.js'
    import Scene from '../js/Poly2/Scene.js'



    //#region gl
    const canvas = document.getElementById("canvas");
    canvas.width = window.innerWidth;
    canvas.height = window.innerHeight - 4;

    const gl = canvas.getContext("webgl", { antialias: true, });

    // gl.enable(gl.DEPTH_TEST);//开始背景遮挡会频闪
    gl.enable(gl.BLEND);
    gl.blendFunc(gl.SRC_ALPHA, gl.ONE_MINUS_SRC_ALPHA);
    gl.pixelStorei(gl.UNPACK_PREMULTIPLY_ALPHA_WEBGL, true);//去图片描边
    //#endregion



    const scene = new Scene({ gl: gl });
    scene.regProgram('color', {
        program: CreateProgram(gl,
            document.querySelector('#ColorVertexShader').innerText,
            document.querySelector('#ColorFragmentShader').innerText),
        attribs: ['a_Position'],
        uniforms: ['u_PointSize', 'u_Color', 'u_ModelM4', 'u_PvM4']
    })

    const defConfig = {
        pointSize: 500,
        color: [1, 1, 1, 1],
    };


    scene.add(createAxis());

    //要计算 两个向量相交的那个点
    //用 当前的点 -> 中心点
    //到 点a -> 点b (依次计算吧,看那个相交的点(这个焦点就在三角形边上)最近)???
    //然后求出相交点到原点的固定倍数点
    // 焦点 到 倍数点 的距离是 1
    // 当前点到焦点的距离就是渐变的a


    {
        let m4 = new Matrix4().makeRotationZ(120 * Math.PI / 180);
        let center = new Vector3(0.5, 0.5, 0);
        let a = new Vector3(0.5, 0.2, 0.0);

        let b = a.clone().sub(center)
            .applyMatrix4(new Matrix4().makeRotationZ(120 * Math.PI / 180))
            .add(center);
        let c = a.clone().sub(center)
            .applyMatrix4(new Matrix4().makeRotationZ(240 * Math.PI / 180))
            .add(center);
        console.log(b, c)
    }


    //交点
    {
        let a1 = new Vector3(-0.5, 0.5);
        let a2 = new Vector3(-0.3, 0.7);

        let b1 = new Vector3(-0.2, 0.5);
        let b2 = new Vector3(-0.2, 0.9);


        scene.add(createNode(a1));
        scene.add(createNode(a2));

        scene.add(createNode(b1, [1, 0, 0, 1]));
        scene.add(createNode(b2, [1, 0, 0, 1]));


        let c = calculateIntersection([a1, a2], [b1, b2]);
        scene.add(createNode(c, [1, 1, 0, 1]));

        console.log(c)


    }


    function calculateIntersection(line1, line2) {
        // 解方程组
        const x1 = line1[0].x;
        const y1 = line1[0].y;
        const x2 = line1[1].x;
        const y2 = line1[1].y;

        const x3 = line2[0].x;
        const y3 = line2[0].y;
        const x4 = line2[1].x;
        const y4 = line2[1].y;

        const denominator = (x1 - x2) * (y3 - y4) - (y1 - y2) * (x3 - x4);

        if (denominator === 0) {
            // 直线平行，没有交点
            return new Vector3(0, 0, 0);
        }

        const intersectionX = ((x1 * y2 - y1 * x2) * (x3 - x4) - (x1 - x2) * (x3 * y4 - y3 * x4)) / denominator;
        const intersectionY = ((x1 * y2 - y1 * x2) * (y3 - y4) - (y1 - y2) * (x3 * y4 - y3 * x4)) / denominator;

        return new Vector3(intersectionX, intersectionY, 0);
    }

    //缩放
    {
        // let a1 = new Vector3(-0.5, 0.5);
        // let b1 = new Vector3(-0.5, 0.1);
        // let c1 = new Vector3(-0.2, 0.3);

        // let m1 = new Vector3(-0.8, 0.8);

        // let center1 = new Vector3(-0.5, 0.5);

        // let scalem4 = new Matrix4().makeScale(0.4, 0.4);
        // let m2 = m1.clone().sub(center1).applyMatrix4(scalem4).add(center1);


        // scene.add(createTriangle(a1, b1, c1, new Matrix4()));

        // scene.add(createNode(m1));
        // scene.add(createNode(m2));


    }


    //返回 1:在 0:在边上 -1:不在
    function inTriangle(node, m) {
        let z = 1;
        for (let i = 0; i < 3; i++) {
            let A = node[i];
            let B = node[(i + 1) % 3];
            let M = m;


            let AB = B.clone().sub(A);
            let AM = M.clone().sub(A);

            //在里面
            if (AB.x * AM.y - AB.y * AM.x < 0) {
                z = -1;
            }
            if (AB.x * AM.y - AB.y * AM.x == 0) {
                z = 0;
                return z;
            }
        }
        return z;
    }






    // let a = new Vector3(0.5, 0.2);
    let a = new Vector3(0.5, 0.84);
    let b = new Vector3(0.2, 0.32);
    let c = new Vector3(0.8, 0.32);

    let m = new Vector3(0.50, 0.50);


    //判断 m 是否在三角形内
    {
        let z = true;
        let node = [a, b, c];
        for (let i = 0; i < 3; i++) {
            let A = node[i];
            let B = node[(i + 1) % 3];
            let M = m;


            let AB = B.clone().sub(A);
            let AM = M.clone().sub(A);

            //叉乘
            if (AB.x * AM.y - AB.y * AM.x > 0) {
                z = false;
                if (z == false) {
                    break;
                }
            }
        }
        // if (z == true) {
        //     console.log('在')
        // } else {
        //     console.log('不在')
        // }
    }

    //旋转三角形
    {
        let center = new Vector3(0.5, 0.5);


        //让本地矩阵旋转
        let a1 = rot(a, center, 30);


        // scene.add(create([a1.x, a1.y], {
        //     pointSize: 10, color: [0, 0, 1, 1]
        // }));


    }

    function rot(node, center, angle) {
        let sub = node.clone().sub(center);
        let j = angle * Math.PI / 180;
        let m4 = new Matrix4(
            Math.cos(j), -Math.sin(j), 0, 0,
            Math.sin(j), Math.cos(j), 0, 0,
            0, 0, 1, 0,
            0, 0, 0, 1
        );
        let a1 = sub.clone().applyMatrix4(m4);
        a1 = a1.add(center);
        return a1;
    }




    scene.add(create([m.x, m.y], {
        pointSize: 10, color: [1, 1, 1, 1]
    }));


    let obja = create([a.x, a.y], {
        pointSize: 10, color: [1, 0, 0, 1]
    });
    scene.add(obja);

    let objb = create([b.x, b.y], {
        pointSize: 10, color: [0, 1, 0, 1]
    });
    scene.add(objb);

    let objc = create([c.x, c.y], {
        pointSize: 10, color: [0, 0, 1, 1]
    });
    scene.add(objc);

    // scene.add(createTriangle(a, b, c, new Matrix4()));

    function createNode(node, color = [1, 1, 1, 1]) {
        return new Obj3D({
            geo: new Geo({
                data: {
                    'a_Position': { size: 2, array: new Float32Array([node.x, node.y]) },
                }
            }),
            mat: new Mat({
                program: 'color',
                mode: ['POINTS'],
                data: {
                    'u_PointSize': { type: 'uniform1f', value: 10 },
                    'u_Color': { type: 'uniform4fv', value: color },
                },
            }),
        });
    }

    function create(node, config) {
        const { pointSize, color } = config;
        return new Obj3D({
            geo: new Geo({
                data: {
                    'a_Position': { size: 2, array: new Float32Array(node) },
                }
            }),
            mat: new Mat({
                program: 'color',
                mode: ['POINTS'],
                data: {
                    'u_PointSize': { type: 'uniform1f', value: pointSize },
                    'u_Color': { type: 'uniform4fv', value: color },
                    'u_ModelM4': { type: 'uniformMatrix4fv', value: new Matrix4().elements },
                    'u_PvM4': { type: 'uniformMatrix4fv', value: new Matrix4().elements },
                },
            }),
        });
    }

    function createTriangle(a, b, c, m4) {
        return new Obj3D({
            geo: new Geo({
                data: {
                    'a_Position': {
                        size: 2, array: new Float32Array([
                            a.x, a.y, b.x, b.y, c.x, c.y
                        ])
                    },
                },
                element: { array: new Uint8Array([0, 1, 1, 2, 2, 0]) }
            }),
            mat: new Mat({
                program: 'color',
                mode: ['LINES'],
                data: {
                    'u_PointSize': { type: 'uniform1f', value: 10 },
                    'u_Color': { type: 'uniform4fv', value: [1, 1, 1, 1] },
                    'u_ModelM4': { type: 'uniformMatrix4fv', value: m4.elements },
                    'u_PvM4': { type: 'uniformMatrix4fv', value: new Matrix4().elements },
                },
            }),
        });
    }

    function createAxis() {
        return new Obj3D({
            geo: new Geo({
                data: {
                    'a_Position': {
                        size: 2, array: new Float32Array([
                            0, 1, 0, -1,
                            1, 0, -1, 0,
                        ])
                    },
                },
                element: { array: new Uint8Array([0, 1, 2, 3]) }
            }),
            mat: new Mat({
                program: 'color',
                mode: ['LINES'],
                data: {
                    'u_PointSize': { type: 'uniform1f', value: 1 },
                    'u_Color': { type: 'uniform4fv', value: [1, 1, 1, 1] },
                    'u_ModelM4': { type: 'uniformMatrix4fv', value: new Matrix4().elements },
                    'u_PvM4': { type: 'uniformMatrix4fv', value: new Matrix4().elements },
                },
            }),
        });
    }

    let angle = 0;
    (function ani() {
        let center = new Vector3(0.5, 0.5, 0);

        angle += 0.1;

        let a1 = rot(a, center, angle);
        obja.setAttrib('a_Position', { array: new Float32Array([a1.x, a1.y]) });
        let b1 = rot(b, center, angle);
        objb.setAttrib('a_Position', { array: new Float32Array([b1.x, b1.y]) });
        let c1 = rot(c, center, angle);
        objc.setAttrib('a_Position', { array: new Float32Array([c1.x, c1.y]) });


        draw();
        requestAnimationFrame(ani);
    })();

    function draw() {
        scene.draw();
    }
</script>

</html>